using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.Events;
using UnityEngine.Networking;

namespace SimpleFramework
{
    // IRequestHandler
    public abstract class RequestCommand : IRequestHandler, ITimer
    {
        protected string m_Url;
        protected int m_State = 0;
        protected UnityWebRequest m_Request;
        protected UnityEvent<IRequestHandler, string> m_Complete = new UnityEvent<IRequestHandler, string>();
        protected Dictionary<string, string> m_Headers = new Dictionary<string, string>();
        protected int m_TryCount = 0;

        public string Url { get { return m_Url; }  set { m_Url = value; } }
        public UnityEvent<IRequestHandler, string> Complete { get { return m_Complete; } }

        public virtual void Reset()
        {
            m_Complete.RemoveAllListeners();
            m_Headers.Clear();
        }

        public void Start()
        {
            m_State = 0;
            m_TryCount = 0;
            m_Request = CreateRequest();
            InitRequestHeader();
            m_Request.SendWebRequest();
            TimerSystem.Instance.Add(this);
        }

        public bool Update()
        {
            if (m_Request.isDone)
            {
                Finish();
                return true;
            }
            else
            {
                return false;
            }
        }

        private void Finish()
        {
            if (m_Request.result == UnityWebRequest.Result.ConnectionError)
            {
                Debug.LogErrorFormat("[LoadFile] URL:{0} Error:{1}", m_Url, m_Request.error);
                if (m_TryCount > 0)
                {
                    m_TryCount--;
                    m_Request = null;
                    m_State = 0;
                }
                else
                {
                    m_Complete.Invoke(this, m_Request.error);
                    m_Request = null;
                    Recycle();
                }
            }
            else
            {
                DownloadHandler handler = m_Request.downloadHandler;
                if (string.IsNullOrEmpty(handler.text) && handler.data.Length == 0)
                {
                    Debug.LogErrorFormat("[LoadFile] URL:{0} Error:{1}", m_Url, m_Request.error);
                    m_Complete.Invoke(this, m_Request.error);
                }
                else
                {
                    m_Complete.Invoke(this, null);
                }
                m_Request = null;
                Recycle();
            }
        }

        protected abstract void Recycle();

        protected abstract UnityWebRequest CreateRequest();

        protected void InitRequestHeader()
        {
            if (m_Headers != null && m_Headers.Count > 0)
            {
                foreach (var pair in m_Headers)
                    m_Request.SetRequestHeader(pair.Key, pair.Value);
            }
        }

        public void SetHeaders(Dictionary<string, string> headers)
        {
            if (headers != null)
            {
                foreach (var pair in headers)
                    m_Headers.Add(pair.Key, pair.Value);
            }
        }

        public T ToJson<T>()
        {
            var data = m_Request.downloadHandler.text;
            return LitJson.JsonMapper.ToObject<T>(data);
        }

        public byte[] ToBytes()
        {
            return m_Request.downloadHandler.data;
        }

        public string ToText()
        {
            return m_Request.downloadHandler.text;
        }
    }
}